package com.ruoyi.web.controller.resourcepool;


import com.alibaba.fastjson.JSON;
import com.ruoyi.common.annotation.BasicFieldFilling;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.DbConfig;
import com.ruoyi.common.constant.ClassesConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.*;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.nlp.protocol.INlpService;
import com.ruoyi.system.domain.SysClasses;
import com.ruoyi.system.domain.SysDataProperty;
import com.ruoyi.system.domain.SysDataType;
import com.ruoyi.system.domain.SysObjectProperty;
import com.ruoyi.system.domain.vo.R;
import com.ruoyi.system.protocol.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.RetrievalUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/system/dynamic")
public class DynamicController extends BaseRetrievalController{

    @Autowired
    private ISysClassesService sysClassesService;

    @Autowired
    private ISysDataPropertyService sysDataPropertyService;


    @Autowired
    private IDynamicDataService dynamicDataService;

    @Autowired
    private IDynamicCacheService dynamicCache;

    @Autowired
    private RetrievalUtil retrievalUtil;

    @Autowired
    private IDynamicSearchService dynamicSearchService;

    @Autowired
    private ISysObjectPropertyService sysObjectPropertyService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IDynamicDataCommonService dynamicDataCommonService;


    @Autowired
    private ServerConfig serverConfig;

    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicController.class);

    /**
     * 获取查询字段
     */
    @PreAuthorize("@ss.hasPermi('system:dynamic:list')")
    @GetMapping("/selectField/{classesId}")
    public R selectField(@PathVariable("classesId") Long classesId) {
        ArrayList<Map<String, Object>> result = new ArrayList<>();
        SysClasses classesListByCache = dynamicCache.findClassesByCache(classesId);
        List<SysDataProperty> dataPropertyListCache = dynamicCache.getDataPropertyListCache(classesListByCache.getNameEn());
        List<SysDataProperty> selectFieldList = dataPropertyListCache.stream().filter(x -> "1".equals(x.getAdminSearchField())).collect(Collectors.toList());
        for (SysDataProperty dataProperty : selectFieldList) {
            Map map = JSON.parseObject(JSON.toJSONString(dataProperty), Map.class);
            SysDataType sysDataType = dynamicCache.findDataTypeByCache(dataProperty.getDataTypeId());
            if ("multiple".equals(sysDataType.getFormType()) || "richText".equals(sysDataType.getFormType())) {
                //文本域与html 使用文本框类型查询
                map.put("fieldType", "string");
            } else if ("dateYear".equals(sysDataType.getFormType()) || "dateYearMonth".equals(sysDataType.getFormType())
                    || "dateYearMonthDay".equals(sysDataType.getFormType()) || "dateTime".equals(sysDataType.getFormType())) {
                //时间类型使用范围查询
                map.put("fieldType", sysDataType.getFormType()+"Range");
            } else {
                map.put("fieldType", sysDataType.getFormType());
            }
            handleSelectObj(result, dataProperty, map);
        }
        return R.success().msg("查询成功").data("searchField", result);
    }

    /**
     * 处理下拉对象
     * @param result
     * @param dataProperty
     * @param map
     */
    private void handleSelectObj(ArrayList<Map<String, Object>> result, SysDataProperty dataProperty, Map map) {
        if (dataProperty.getDictId() != null && dataProperty.getDictId() != 0) {
            SysDictType dictTypeByCache = dynamicCache.findDictTypeByCache(dataProperty.getDictId());
            List<SysDictData> sysDictData = dictTypeByCache.getDictDataList();
            ArrayList<Map> dictDataList = new ArrayList<>();
            sysDictData.forEach(item -> {
                Map dictDataMap = new HashMap();
                dictDataMap.put("id", item.getDictCode());
                dictDataMap.put("label", item.getDictLabel());
                dictDataMap.put("value", item.getDictValue());
                dictDataMap.put("pid", item.getPid());
                dictDataList.add(dictDataMap);
            });
            map.put("selectObj", dictDataList);
        }
        result.add(map);
    }

    /**
     * 获取详情展示字段
     */
    @PreAuthorize("@ss.hasPermi('system:dynamic:add')")
    @GetMapping("/detailsField/{classesId}")
    public R detailsField(@PathVariable("classesId") Long classesId) {
        ArrayList<Map<String, Object>> result = new ArrayList<>();
        //详情显示
        SysClasses classesListByCache = dynamicCache.findClassesByCache(classesId);
        List<SysDataProperty> dataPropertyListCache = dynamicCache.getDataPropertyListCache(classesListByCache.getNameEn());
        List<SysDataProperty> showDetail = dataPropertyListCache.stream().filter(x -> "1".equals(x.getAdminDetailShow())).collect(Collectors.toList());
        showDetail = showDetail.stream().map(x->{
            if(x.getSort() == null){
                x.setSort(0L);
            }
            return x;
        }).sorted(Comparator.comparing(x -> x.getSort())).collect(Collectors.toList());
        for (SysDataProperty dataProperty : showDetail) {
            Map map = JSON.parseObject(JSON.toJSONString(dataProperty), Map.class);
            SysDataType sysDataType = dynamicCache.findDataTypeByCache(dataProperty.getDataTypeId());
            map.put("fieldType", sysDataType.getFormType());
            handleSelectObj(result, dataProperty, map);
        }
        return R.success().msg("查询成功").data("detailField", result);
    }

    /**
     * 审核资源
     */
    @PreAuthorize("@ss.hasPermi('system:dynamic:audit')")
    @Log(title = "知识库管理", businessType = BusinessType.DELETE)
    @PostMapping("/audit")
    public AjaxResult audit(@RequestBody HashMap<String, Object> dynamic){
        List<String> idsList = (List<String>) dynamic.get("ids");
        String classesIdStr = dynamic.get("classesId") + "";
        String status = dynamic.get("status") + "";
        String refuseExplain = dynamic.get("refuseExplain") + "";

        Long classesId = Long.parseLong(classesIdStr);
        SysClasses sysClasses = dynamicCache.findClassesByCache(classesId);
        HashMap<String, Object> dynamicData = new HashMap<>();
        dynamicData.put("status", status);
        dynamicData.put("refuse_explain", refuseExplain);
        HashMap<String, Object> codition = new HashMap<>();
        codition.put("in,id", idsList);
        dynamicDataService.editDynamicData(sysClasses.getNameEn(), dynamicData, codition);
        return AjaxResult.success("审核成功");
    }


    /**
     * 新增知识库数据
     */
    @BasicFieldFilling(filterType = "dynamic", operationType = "add")
    @DataScope(filterType = "dynamic")
    @PreAuthorize("@ss.hasPermi('system:dynamic:add')")
    @Log(title = "知识库管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public AjaxResult add(@RequestBody HashMap<String, Object> dynamic){
        String classesIdStr = dynamic.get("classesId") + "";
        if(StringUtils.isNotBlank(classesIdStr) && !"null".equals(classesIdStr)){
            Long classesId = Long.parseLong(classesIdStr);
            SysClasses sysClasses = dynamicCache.findClassesByCache(classesId);
            handleFilePrefix(sysClasses.getNameEn(), dynamic, "enter");
            String id = dynamicDataService.addDynamicData(sysClasses.getNameEn(), dynamic);
            return AjaxResult.success("新增成功").put("id", id);
        }
        return AjaxResult.error("新增失败");
    }

    /**
     * 修改知识库
     */
    @BasicFieldFilling(filterType = "dynamic", operationType = "edit")
    @PreAuthorize("@ss.hasPermi('system:dynamic:edit')")
    @Log(title = "知识库管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    public AjaxResult edit(@RequestBody HashMap<String, Object> dynamic){
        String classesIdStr = dynamic.get("classesId") + "";
        if(StringUtils.isNotBlank(classesIdStr) && !"null".equals(classesIdStr)){
            Long classesId = Long.parseLong(classesIdStr);
            SysClasses sysClasses = dynamicCache.findClassesByCache(classesId);
            List<SysDataProperty> dataPropertyListCache = dynamicCache.getDataPropertyListCache(sysClasses.getNameEn());
            List<String> editField = dataPropertyListCache.stream().filter(x -> "0".equals(x.getAllowModification())).map(x -> x.getNameEn()).collect(Collectors.toList());
            for (String field : editField) {
                dynamic.remove(field);
            }
            HashMap<String, Object> codition = new HashMap<>();
            codition.put("=,id", dynamic.get("id")+"");
            handleFilePrefix(sysClasses.getNameEn(), dynamic, "enter");
            dynamicDataService.editDynamicData(sysClasses.getNameEn(), dynamic, codition);
            return AjaxResult.success("修改成功");
        }
        return AjaxResult.error("修改失败");
    }


    /**
     * 删除知识库数据
     */
    @PreAuthorize("@ss.hasPermi('system:dynamic:remove')")
    @Log(title = "知识库管理", businessType = BusinessType.DELETE)
    @PostMapping("/del")
    public AjaxResult del(@RequestBody HashMap<String, Object> dynamic){
        String classesIdStr = dynamic.get("classesId") + "";
        List<String> idsList = (List<String>) dynamic.get("ids");
        if(StringUtils.isNotBlank(classesIdStr) && !"null".equals(classesIdStr) && idsList.size() > 0){
            String ids = idsList.stream().collect(Collectors.joining(","));
            Long classesId = Long.parseLong(classesIdStr);
            SysClasses sysClasses = dynamicCache.findClassesByCache(classesId);
            HashMap<String, Object> codition = new HashMap<>();
            codition.put("in,id", ids);
            dynamicDataService.delDynamicData(sysClasses.getNameEn(), codition);
            dynamicSearchService.deleteDocument(ClassesConstants.ELASTICSEARCH_INDEXES, idsList);
            return AjaxResult.success("删除成功");
        }
        return AjaxResult.error("删除失败");
    }

    /**
     * 根据id查询知识库
     */
    @PreAuthorize("@ss.hasPermi('system:dynamic:query')")
    @GetMapping(value = "find/{classesId}/{id}")
    public AjaxResult getInfo(@PathVariable("classesId") Long classesId,@PathVariable("id") String id)
    {
        SysClasses sysClasses = dynamicCache.findClassesByCache(classesId);
        Map<String, Object> dynamicData = dynamicDataService.findDynamicData(sysClasses.getNameEn(), null, id);
        handleFilePrefix(sysClasses.getNameEn(), dynamicData, "out");
        return AjaxResult.success(dynamicData);
    }


    //动态资源库用户部门查询下拉
    @PreAuthorize("@ss.hasPermi('system:dynamic:list')")
    @PostMapping(value = "dynamicDataUserDepartmentQueryConditions")
    public R dynamicDataQueryConditions() {
        SysUser sysUser = new SysUser();
        List<SysUser> userList = sysUserService.selectUserList(sysUser);
        List<Map<String, Object>> userListResult = new ArrayList<>();
        Map<String, Object> tmpUser = null;
        for (SysUser user : userList) {
            tmpUser = new HashMap<>();
            tmpUser.put("userId", user.getUserId());
            tmpUser.put("nickName", user.getNickName());
            tmpUser.put("userName", user.getUserName());
            tmpUser.put("deptName", user.getDept().getDeptName());
            userListResult.add(tmpUser);
        }

        SysDept sysDept = new SysDept();
        List<SysDept> deptList = sysDeptService.selectDeptList(sysDept);
        List<SysDept> deptListResult = new ArrayList<>();
        SysDept tmpDept = null;
        for (SysDept dept : deptList) {
            tmpDept = new SysDept();
            tmpDept.setDeptId(dept.getDeptId());
            tmpDept.setDeptName(dept.getDeptName());
            deptListResult.add(tmpDept);
        }

        return R.success().data("userList", userListResult).data("deptList", deptListResult);
    }

    /**
     * 查询知识列表
     */
    @DataScope(filterType = "dynamic")
    @PreAuthorize("@ss.hasPermi('system:dynamic:list')")
    @GetMapping("/list")
    public R list(SysDataScope sysDataScope) {
        Long classesId = Long.parseLong(ServletUtils.getParameter("classesId"));
        SysClasses sysClasses = dynamicCache.findClassesByCache(classesId);
        List<SysDataProperty> dataPropertyListCache = dynamicCache.getDataPropertyListCache(sysClasses.getNameEn());
        //查询条件项
        List<SysDataProperty> selectFieldList = dataPropertyListCache.stream().filter(x -> "1".equals(x.getAdminSearchField())).collect(Collectors.toList());
        //列表显示
        List<SysDataProperty> showList = dataPropertyListCache.stream().filter(x -> "1".equals(x.getAdminListShow())).collect(Collectors.toList());
        for (SysDataProperty sysDataProperty : showList) {
            if("selectSingle".equals(sysDataProperty.getDataTypeName()) || "selectMultiple".equals(sysDataProperty.getDataTypeName())){
                SysDictType dictTypeByCache = dynamicCache.findDictTypeByCache(sysDataProperty.getDictId());
                sysDataProperty.setDictType(dictTypeByCache);
            }
        }
        List<String> selectField = showList.stream().map(SysDataProperty::getNameEn).collect(Collectors.toList());
        HashMap<String, Object> conditon = new HashMap<>();
        for (SysDataProperty dataProperty : selectFieldList) {
            SysDataType sysDataType = dynamicCache.findDataTypeByCache(dataProperty.getDataTypeId());
            if("between".equals(sysDataType.getQueryRules())){
                String start_parameter = ServletUtils.getParameter("start_"+dataProperty.getNameEn());
                String end_parameter = ServletUtils.getParameter("end_"+dataProperty.getNameEn());
                if(StringUtils.isNotBlank(start_parameter)){
                    conditon.put(">=,"+dataProperty.getNameEn(), start_parameter);
                }
                if(StringUtils.isNotBlank(end_parameter)){
                    conditon.put("<=,"+dataProperty.getNameEn(), end_parameter);
                }
            }else{
                String parameter = ServletUtils.getParameter(dataProperty.getNameEn());
                if(StringUtils.isNotBlank(parameter)){
                    conditon.put(sysDataType.getQueryRules()+","+dataProperty.getNameEn(), parameter);
                }
            }
        }
        HashMap<String, Object> sortConditon = new HashMap<>();
        String orderByCol = ServletUtils.getParameter(TableSupport.ORDER_BY_COLUMN);
        String isAsc = ServletUtils.getParameter(TableSupport.IS_ASC);
        if(StringUtils.isNotBlank(orderByCol) && StringUtils.isNotBlank(isAsc)){
            sortConditon.put(orderByCol, isAsc);
        }
        dataRangeFiltering(sysDataScope.getParams(), conditon);


        //基础字段查询-START
        String status = ServletUtils.getParameter("status");
        if(StringUtils.isNotBlank(status)){
            conditon.put("=,status", status);
        }
        String startCreateTime = ServletUtils.getParameter("start_createTime");
        if(StringUtils.isNotBlank(startCreateTime)){
            conditon.put(">=,create_time", startCreateTime+" 00:00:00");
        }
        String endCreateTime = ServletUtils.getParameter("end_createTime");
        if(StringUtils.isNotBlank(endCreateTime)){
            conditon.put("<=,create_time", endCreateTime+" 23:59:59");
        }
        String createUserId = ServletUtils.getParameter("createUserId");
        if(StringUtils.isNotBlank(createUserId)){
            conditon.put("=,create_user_id", createUserId);
        }
        String createDeptId = ServletUtils.getParameter("createDeptId");
        if(StringUtils.isNotBlank(createDeptId)){
            conditon.put("=,create_dept_id", createDeptId);
        }
        //基础字段查询-END
        List<Map<String, Object>> dynamicData = dynamicDataService.getDynamicData(sysClasses.getNameEn(), selectField,
                conditon, sortConditon, ServletUtils.getParameterToInt(TableSupport.PAGE_NUM), ServletUtils.getParameterToInt(TableSupport.PAGE_SIZE));
        Long dynamicCount = dynamicDataService.getDynamicDataCount(sysClasses.getNameEn(), conditon);
        return R.success().msg("查询成功").data("list", dynamicData).data("total", dynamicCount).data("showField", showList);
    }

    @PreAuthorize("@ss.hasPermi('system:dynamic:withdraw')")
    @PostMapping(value = "withdrawResource")
    public AjaxResult withdrawResource(@RequestBody HashMap<String, Object> dynamic) {
        List<String> ids = (List<String>) dynamic.get("resourceIds");
        dynamicSearchService.deleteDocument(ClassesConstants.ELASTICSEARCH_INDEXES, ids);
        return AjaxResult.success();
    }

    @PreAuthorize("@ss.hasPermi('system:dynamic:release')")
    @PostMapping(value = "releaseClasses")
    public AjaxResult releaseClasses(@RequestBody HashMap<String, Object> dynamic) {
        Object classesIds = dynamic.get("classesIds");
        List<String> ids = new ArrayList<>();
        if(classesIds instanceof ArrayList){
            ids.addAll((List<String>)classesIds);
        }else{
            ids.add(classesIds.toString());
        }
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (Object id : ids) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    publishClass(id);
                }
            });
        }
        //关闭线程池
        executorService.shutdown();
        while(true){
            if(executorService.isTerminated()){
                LOGGER.info("所有的子线程都结束了!");
                break;
            }
        }
        return AjaxResult.success();
    }

    private void publishClass(Object id){
        SysClasses sysClasses = dynamicCache.findClassesByCache(Long.parseLong(id+""));
        List<SysDataProperty> dataPropertyListCache = dynamicCache.getDataPropertyListCache(sysClasses.getNameEn());
        List<SysDataProperty> sysDataProperties = dataPropertyListCache.stream().filter(x -> "1".equals(x.getIndexed())).collect(Collectors.toList());
        HashMap<String, String> elasticSearchFieldPrefix = new HashMap<>();
        HashMap<String, String> elasticSearchMultiFields = new HashMap<>();
        for (SysDataProperty sysDataProperty : sysDataProperties) {
            elasticSearchFieldPrefix.put(sysDataProperty.getNameEn(), sysDataProperty.getSearchNameEn());
            if("1".equals(sysDataProperty.getMultiValued())){
                if(StringUtils.isNotBlank(sysDataProperty.getSeparator())){
                    elasticSearchMultiFields.put(sysDataProperty.getNameEn(), sysDataProperty.getSeparator());
                }else{
                    elasticSearchMultiFields.put(sysDataProperty.getNameEn(), "≡");
                }
            }
        }
        List<String> selectField = sysDataProperties.stream().map(SysDataProperty::getNameEn).collect(Collectors.toList());
        String type = sysClasses.getNameEn();
        Long dynamicCount = dynamicDataService.getDynamicDataCount(type, null);
        int maxPageNum = new Double(Math.ceil(1.0 * dynamicCount / ClassesConstants.RELEASE_NUMBER_EVERT_TIME)).intValue();
        HashMap<String, Object> conditon = new HashMap<>();
        HashMap<String, Object> sortConditon = new HashMap<>();
        sortConditon.put("id", "asc");
        String startId = "0";
        for (int i = 0; i < maxPageNum; i++) {
            conditon.put(">,id", startId);
            List<Map<String, Object>> dynamicData = dynamicDataService.getDynamicData(type, selectField, conditon, sortConditon, 1, ClassesConstants.RELEASE_NUMBER_EVERT_TIME);
            List<Object> documentList = new ArrayList<>();
            for (Map<String, Object> dynamicDatum : dynamicData) {
                dynamicDatum.put("dbEn",  sysClasses.getDb());
                dynamicDatum.put("dbZh", sysClasses.getDbZh());
                dynamicDatum.put("type", type);
                dynamicDatum.put("classEn", type);
                dynamicDatum.put("classZh", sysClasses.getNameZh());
            }
            Map<String, Object> dynamicDatumAdd = null;
            List<String> dynamicDatumDel = null;
            for (Map<String, Object> dynamicDatum : dynamicData) {
                dynamicDatumAdd = new HashMap<>();
                dynamicDatumDel = new ArrayList<>();
                for(String key: dynamicDatum.keySet()){
                    String dynamicVal = dynamicDatum.get(key) + "";
                    String keyForward = retrievalUtil.replaceRetrievalFieldForward(key);
                    if(StringUtils.isNotBlank(dynamicVal) && !"null".equals(dynamicVal)){
                        if(elasticSearchMultiFields.containsKey(key)){
                            List<String> list = Arrays.asList(dynamicVal.split(elasticSearchMultiFields.get(key)));
                            dynamicDatumAdd.put(keyForward, list);
                        }else{
                            dynamicDatumAdd.put(keyForward, dynamicVal);
                        }
                    }
                    if(!Objects.equals(key, keyForward)){
                        dynamicDatumDel.add(key);
                    }
                }
                dynamicDatum.putAll(dynamicDatumAdd);
                for (String delKey : dynamicDatumDel) {
                    dynamicDatum.remove(delKey);
                }
                documentList.add(dynamicDatum);
            }
            getLinkedData(sysClasses.getId(), type, documentList);
            dynamicSearchService.batchCreateDocument(documentList, ClassesConstants.ELASTICSEARCH_INDEXES);
            startId = dynamicData.get(dynamicData.size() - 1).get("id") + "";
            LOGGER.info("资源库{}已发布{}%", sysClasses.getNameZh(), String.format("%.2f", (i*1.0 / maxPageNum) * 100));
        }
        LOGGER.info("资源库{}发布完成", sysClasses.getNameZh());
    }

    @PreAuthorize("@ss.hasPermi('system:dynamic:release')")
    @PostMapping(value = "releaseResource")
    public AjaxResult releaseResource(@RequestBody HashMap<String, Object> dynamic) {
        Long classesId = Long.parseLong(dynamic.get("classesId")+"");
        List<String> ids = (List<String>) dynamic.get("resourceIds");
        String idsStr = "";
        for (String id : ids) {
            idsStr += Long.parseLong(id+"") + ",";
        }
        if (idsStr.endsWith(",")) {
            idsStr = idsStr.substring(0, idsStr.length() - 1);
        }
        SysClasses sysClasses = dynamicCache.findClassesByCache(classesId);
        List<SysDataProperty> dataPropertyListCache = dynamicCache.getDataPropertyListCache(sysClasses.getNameEn());
        List<SysDataProperty> sysDataProperties = dataPropertyListCache.stream().filter(x -> "1".equals(x.getIndexed())).collect(Collectors.toList());
        HashMap<String, String> elasticSearchFieldPrefix = new HashMap<>();
        HashMap<String, String> elasticSearchMultiFields = new HashMap<>();
        for (SysDataProperty sysDataProperty : sysDataProperties) {
            elasticSearchFieldPrefix.put(sysDataProperty.getNameEn(), sysDataProperty.getSearchNameEn());
            if("1".equals(sysDataProperty.getMultiValued())){
                if(StringUtils.isNotBlank(sysDataProperty.getSeparator())){
                    elasticSearchMultiFields.put(sysDataProperty.getNameEn(), sysDataProperty.getSeparator());
                }else{
                    elasticSearchMultiFields.put(sysDataProperty.getNameEn(), "≡");
                }
            }
        }
        List<String> selectField = sysDataProperties.stream().map(SysDataProperty::getNameEn).collect(Collectors.toList());
        String type = sysClasses.getNameEn();
        HashMap<String, Object> conditon = new HashMap<>();
        conditon.put("in,id", idsStr);
        List<Map<String, Object>> dynamicData = dynamicDataService.getDynamicData(type, selectField, conditon, null, 1, ClassesConstants.RELEASE_NUMBER_EVERT_TIME);
        List<Object> documentList = new ArrayList<>();
        for (Map<String, Object> dynamicDatum : dynamicData) {
            dynamicDatum.put("dbEn",  sysClasses.getDb());
            dynamicDatum.put("dbZh", sysClasses.getDbZh());
            dynamicDatum.put("type", type);
            dynamicDatum.put("classEn", type);
            dynamicDatum.put("classZh", sysClasses.getNameZh());
        }
        Map<String, Object> dynamicDatumAdd = null;
        List<String> dynamicDatumDel = null;
        for (Map<String, Object> dynamicDatum : dynamicData) {
            dynamicDatumAdd = new HashMap<>();
            dynamicDatumDel = new ArrayList<>();
            for(String key: dynamicDatum.keySet()){
                String dynamicVal = dynamicDatum.get(key) + "";
                String keyForward = retrievalUtil.replaceRetrievalFieldForward(key);
                if(StringUtils.isNotBlank(dynamicVal) && !"null".equals(dynamicVal)){
                    if(elasticSearchMultiFields.containsKey(key)){
                        List<String> list = Arrays.asList(dynamicVal.split(elasticSearchMultiFields.get(key)));
                        dynamicDatumAdd.put(keyForward, list);
                    }else{
                        dynamicDatumAdd.put(keyForward, dynamicVal);
                    }
                }
                if(!Objects.equals(key, keyForward)){
                    dynamicDatumDel.add(key);
                }
            }
            dynamicDatum.putAll(dynamicDatumAdd);
            for (String delKey : dynamicDatumDel) {
                dynamicDatum.remove(delKey);
            }


            documentList.add(dynamicDatum);
        }
        getLinkedData(classesId, type, documentList);
        dynamicSearchService.batchCreateDocument(documentList, ClassesConstants.ELASTICSEARCH_INDEXES);
        return AjaxResult.success();
    }

    /**
     * 获取关联数据
     */
    public void getLinkedData(Long classesId, String classesEn, List<Object> documentList){
        SysObjectProperty sysObjectProperty = new SysObjectProperty();
        sysObjectProperty.setClassesId(classesId);
        List<SysObjectProperty> objectPropertyList = sysObjectPropertyService.selectSysObjectPropertyList(sysObjectProperty);
        SysClasses targetClasses = null;
        Map<String, Object> condition = null;
        String[] relevanceClassFieldsArr = null;
        List<SysDataProperty> dataPropertyListCache = null;
        SysDataProperty sysDataProperty = null;
        List<Map<String, Object>> dynamicOpData = null;
        List<Map<String, Object>> ObjectPropertypDataList = null;
        for (Object o : documentList) {
            Map<String, Object> data = (Map<String, Object>)o;
            String id = data.get("id") + "";
            if(StringUtils.isNotBlank(id)){
                for (SysObjectProperty objectProperty : objectPropertyList) {
                    targetClasses = dynamicCache.findClassesByCache(objectProperty.getRelevanceClassesId());
                    dataPropertyListCache = dynamicCache.getDataPropertyListCache(targetClasses.getId()+"");
                    List<String> opSelectFields = new ArrayList<>();
                    condition = new HashMap<>();
                    condition.put("=,source_data_id", id);
                    String tableName = ClassesConstants.RESOURCE_TABLE_PREFIX+classesEn+"_"+objectProperty.getField();
                    ObjectPropertypDataList = dynamicDataCommonService.getDynamicData(tableName, null, condition, null, 1, Integer.MAX_VALUE);
                    if(ObjectPropertypDataList.size() > 0){
                        String relevanceClassFields = objectProperty.getRelevanceClassFields();
                        relevanceClassFieldsArr = relevanceClassFields.split(",");
                        for (String dataPropertyId : relevanceClassFieldsArr) {
                            sysDataProperty = dataPropertyListCache.stream().filter(x -> (x.getId() + "").equals(dataPropertyId)).findFirst().orElse(null);
                            if(sysDataProperty != null){
                                opSelectFields.add(sysDataProperty.getNameEn());
                            }
                        }
                        condition = new HashMap<>();
                        condition.put("in,id", ObjectPropertypDataList.stream().map(x -> x.get("target_data_id") + "").collect(Collectors.toList()));
                        dynamicOpData = dynamicDataCommonService.getDynamicData(ClassesConstants.RESOURCE_TABLE_PREFIX+targetClasses.getNameEn(), opSelectFields, condition, null, 1, ObjectPropertypDataList.size());
                        data.put(objectProperty.getField(), dynamicOpData);
                    }
                }
            }
        }
    }
}
